在昨天的 [Day 06] 中,我們在 Google AI Studio 沙盒裡完成了 OmniVibe AI 專屬 System Prompt 的淬鍊,並敲定了最佳的超參數設定(gemini-1.5-flash、Temperature: 0.4)。
今天,我們要把這份在試驗場中驗證成功的 AI 大腦,以生產級代碼正式整合進我們的 Next.js 全棧專案中。
很多剛接觸 AI 開發的朋友會問:「官方 SDK 不是支援瀏覽器客戶端直接發請求嗎?為什麼一定要透過後端 API Route 轉發?」
答案只有兩個字:安全與控制。
GEMINI_API_KEY 依然能被惡意使用者在 Network 面板中抓出並盜用。今天我們將一步一腳印,使用最新版的 Google Gen AI SDK,在 Next.js App Router 中實作這支核心端點!
在專案終端機中,安裝 Google 官方維護的 Generative AI SDK:
npm install @google/generative-ai
確認你的 package.json 已經成功寫入相依套件,且專案目錄下的 .env.local 已經正確填入 Day 05 申請的 GEMINI_API_KEY:
# .env.local
GEMINI_API_KEY="AIzaSy_YOUR_GEMINI_API_KEY_HERE"
為了避免在每次收到 HTTP 請求時都重複建立客戶端實例,同時保持代碼的高內聚力,我們在 src/lib 目錄下進行模組化封裝。
src/lib/gemini/prompts.ts)將我們在 Day 06 調校好的頂級內容架構師 System Instruction 獨立維護:
export const OMNIVIBE_SYSTEM_INSTRUCTION = `
# Role & Identity
你是一位全球頂尖的「全媒體內容策略師與知識架構師」。你的專長是從龐雜、冗長的多模態資料(訪談、逐字稿、研究白皮書、筆記)中,以手術刀般的精準度提煉出核心洞見,並重組為具傳播力且符合各社群平台特性的內容矩陣。
# Core Objectives
當用戶提供輸入內容時,你必須遵循以下規範產出繁體中文成果:
1. 【洞見萃取 (Distillation)】:提煉 3~5 個核心實踐論點(Core Takeaways)。
2. 【結構化轉譯 (Transformation)】:
- A. 社群爆款貼文(Threads / X 風格,具吸引人的開頭 Hook 與條列式乾貨)
- B. 短影音口播分鏡腳本(前 3 秒黃金吸睛台詞、節奏指示)
- C. 決策精華筆記(金字塔原理摘要與行動指南)
3. 【嚴格防幻覺】:所有觀點必須忠於原文材料,禁止胡亂拼湊或無中生有。
# Formatting Constraints
- 語氣:自然、專業且富有啟發性,嚴禁使用陳詞濫調的官腔套話。
- 排版:使用清晰的 Markdown 階層語法,善用加粗與清單。
`;
src/lib/gemini/client.ts)import { GoogleGenerativeAI, GenerationConfig } from '@google/generative-ai';
import { OMNIVIBE_SYSTEM_INSTRUCTION } from './prompts';
if (!process.env.GEMINI_API_KEY) {
throw new Error('Missing GEMINI_API_KEY in environment variables.');
}
// 建立全域單例客戶端
const genAI = new GoogleGenerativeAI(process.env.GEMINI_API_KEY);
// 定義與 Day 06 調優完全一致的超參數
const defaultGenerationConfig: GenerationConfig = {
temperature: 0.4,
topP: 0.95,
topK: 40,
maxOutputTokens: 4096,
};
/**
* 取得配置好的 Gemini 內容提煉模型實例
*/
export function getOmniVibeModel(modelName: string = 'gemini-1.5-flash') {
return genAI.getGenerativeModel({
model: modelName,
systemInstruction: OMNIVIBE_SYSTEM_INSTRUCTION,
generationConfig: defaultGenerationConfig,
});
}
在 Next.js App Router 中,API 端點以 route.ts 命名。我們建立 src/app/api/ai/transform/route.ts 來處理內容提煉請求。
這支 API 具備防禦性編程(Defensive Programming)機制:
// src/app/api/ai/transform/route.ts
import { NextRequest, NextResponse } from 'next/server';
import { getOmniVibeModel } from '@/lib/gemini/client';
// 定義 Request Body 結構
interface TransformRequestBody {
content: string;
targetFormat?: 'all' | 'threads' | 'script' | 'summary';
}
export async function POST(req: NextRequest) {
try {
const body: TransformRequestBody = await req.json();
const { content, targetFormat = 'all' } = body;
// 1. 輸入邊界檢查
if (!content || typeof content !== 'string') {
return NextResponse.json(
{ error: 'Bad Request', message: '欄位 content 必須為非空白字串' },
{ status: 400 }
);
}
if (content.trim().length < 20) {
return NextResponse.json(
{ error: 'Bad Request', message: '輸入內容過短,請提供至少 20 字以上的材料' },
{ status: 400 }
);
}
// 2. 獲取調教好的模型實例
const model = getOmniVibeModel('gemini-1.5-flash');
// 3. 動態微調 Prompt 意圖
let promptTask = `以下是使用者提供的原始內容,請依據系統規範進行深度知識提煉與轉譯:\n\n${content}`;
if (targetFormat !== 'all') {
promptTask += `\n\n【特別指示】:本次產出請集中強化格式 [${targetFormat}]。`;
}
// 4. 調用 Gemini API 生成內容
const result = await model.generateContent(promptTask);
const response = await result.response;
const outputText = response.text();
// 5. 成功回傳
return NextResponse.json({
success: true,
data: {
rawOutput: outputText,
usageMetadata: response.usageMetadata, // 包含 Prompt/Candidate Token 消耗
},
meta: {
model: 'gemini-1.5-flash',
timestamp: new Date().toISOString(),
},
});
} catch (error: any) {
console.error('[Gemini API Route Error]:', error);
// 針對 Google AI 常見錯誤做優雅降級
if (error.status === 429) {
return NextResponse.json(
{ error: 'Too Many Requests', message: '目前 AI 調用頻率過高,請稍候重試' },
{ status: 429 }
);
}
return NextResponse.json(
{ error: 'Internal Server Error', message: error.message || 'AI 處理過程發生非預期錯誤' },
{ status: 500 }
);
}
}
伺服器啟動中(npm run dev),我們可以使用終端機的 curl 指令或 VS Code 內的 REST Client 擴充套件,直接對 http://localhost:3000/api/ai/transform 發動測試:
curl -X POST http://localhost:3000/api/ai/transform \
-H "Content-Type: application/json" \
-d '{
"content": "很多人覺得全端工程師就是要什麼都自己寫。但現在是 Vibe Coding 的時代,把架構想清楚、用自然語言指導 AI,兩週做出來的成果比過去三個月手刻還要穩定。核心在於你能不能精確定義 PRD 和懂得調教 Prompt。"
}'
{
"success": true,
"data": {
"rawOutput": "### 💡 核心洞見 (Core Takeaways)\n1. **開發範式轉移**:Vibe Coding 改變了傳統全端手刻代碼的流程,強調高階架構規劃...\n\n---\n### 📱 A. Threads / X 爆款貼文\n為什麼現在還有人在手刻所有代碼?...",
"usageMetadata": {
"promptTokenCount": 286,
"candidatesTokenCount": 420,
"totalTokenCount": 706
}
},
"meta": {
"model": "gemini-1.5-flash",
"timestamp": "2026-09-21T00:00:00.000Z"
}
}
終端機在不到 1.5 秒內即噴出排版精美的結構化回應,且 usageMetadata 精準記錄了本次請求消耗的 Token 數量,這對後續計算用戶額度極具價值!
今天我們成功達成了以下重要里程碑:
/api/ai/transform 端點,並完成了實際連通測試。目前我們的 API 已經能完美處理純文字輸入,但 OmniVibe AI 的殺手級功能是:直接吃下長篇 PDF、數萬字財報白皮書與整本電子書!
👉 明天(Day 08),我們將進入【長文本魔法篇】:實戰百萬級 Token 處理!看我們如何利用 Gemini 原生超長上下文視窗與 File 上傳機制,讓 AI 一次性吞下整份厚重 PDF,並精準抓出關鍵洞見!
敬請期待,我們明天見!🔥